<?php
/**
* 如果有 Redis 则使用，否则使用文件
*/
class _Cache{
	protected $_prefix = '';
	protected $support_redis = false;
	protected $_cache_dir = "data/cache";
	protected $_redis;
	
	function __construct(){
		if(!file_exists($this->_cache_dir)) mkdir($this->_cache_dir);
		//$this->support_redis = in_array("Zend OPcache", get_loaded_extensions());
		$this->support_redis = in_array("redis", get_loaded_extensions());
		if($this->support_redis){
			$this->_redis = new Redis();
			$this->_redis->connect("127.0.0.1",6379);
			$this->_redis->auth("foobared");
			$this->_redis->select(0); // switch to DB 0
		}
		
		function __destruct(){
			if($this->support_redis) $this->_redis = null;
		}
		
	}
	
	
	/**
	 * 判断缓存变量是否存在
	 * @param string $key
	 * @return bool
	 */
	public function exists($key){
		if($this->support_redis){
			return $this->_redis->exists($key);
		}else{
			$_cache_file = $this->_cache_dir. "/". md5($this->_storageKey ( $key ));
			if(!file_exists($_cache_file)) return false;
			// 读取文件，判断是否超时，如果超时则删掉
			$data = file_get_contents($_cache_file);
			$property = substr($data, 0, strpos($data, "|"));
			list($type, $expire) = explode(",", $property);
			// 获取缓存时间
			$create_time = filectime($_cache_file);
			if($expire>0){	// 如果有过期时间
				if(time()-$create_time > $expire) {		// 已超时
					unlink($_cache_file);
					return false;
				}
			}
			return true;
		}
	}
	
	
	/**
	 * 读缓存变量
	 *
	 * @param string $key
	 * @return mixed
	 */
	public function fetch($key) {
		if($this->support_redis){
			$data = $this->_redis->get($key);
			$type = substr($data, 0, strpos($data, "|"));

		}else{
			$_cache_file = $this->_cache_dir. "/". md5($this->_storageKey ( $key ));
			if(!file_exists($_cache_file)) return false;
			$data = file_get_contents($_cache_file);
			$property = substr($data, 0, strpos($data, "|"));
			list($type, $expire) = explode(",", $property);
			// 获取缓存时间
			$create_time = filectime($_cache_file);
			if($expire>0){	// 如果有过期时间
				if(time()-$create_time > $expire) {		// 已超时
					unlink($_cache_file);
					return false;
				}
			}
		}
		
		$data = substr($data, strpos($data, "|")+1);
		if($type == "arr") $data =unserialize(base64_decode($data));
		else $data = base64_decode($data);
		return $data;
		
	}
	
	
	/**
	 * 缓存变量
	 *
	 * @param string $key
	 * @param string $value
	 * @return bool
	 */
	function store($key, $val, $time=0){
		if($this->support_redis){
			if(is_array($val)) $val = "arr|". base64_encode(serialize($val));
			else $val = "str|". base64_encode($val);
			if($time){
				return $this->_redis->setex($key, $time, $val);
			}else{
				return $this->_redis->set($key, $val);
			}
		}else{
			$_cache_file = $this->_cache_dir. "/". md5($this->_storageKey ( $key ));
			if(file_exists($_cache_file)) unlink($_cache_file);
			if(is_array($val)) $val = "arr,{$time}|". base64_encode(serialize($val));
			else $val = "str,{$time}|". base64_encode($val);
			file_put_contents($_cache_file, $val);
			return true;
		}
	}
	
	
	/**
	 * 删除缓存变量
	 *
	 * @param string $key
	 * @return bool
	 */
	public function delete($key) {
		if($this->support_redis){
			return $this->_redis->delete($key);
		}else{
			$_cache_file = $this->_cache_dir. "/". md5($this->_storageKey ( $key ));
			if(file_exists($_cache_file)){
				unlink($_cache_file);
				return true;
			}else{
				return false;
			}
		}
	}
	
	
	/**
	 * 清(删)除所有缓存
	 *
	 * @return bool
	 */
	public function clear() {
		if($this->support_redis){
			return $this->_redis->flushDB();
		}else{
			$fp=opendir($this->_cache_dir);
			while (false !== ($fstr=readdir($fp))){
				if ($fstr != "." && $fstr != "..") {
					if(is_file($this->_cache_dir .'/'.$fstr)){
						unlink($this->_cache_dir .'/'.$fstr);
					}
				}
			}		
			return true;
		}
	}
	
	
	
	
	private function _storageKey($key) {
		return $this->_prefix . '_' . $key;
	}
	
	
}
?>